package org.lc.eic.messagingsystem.activemq;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;

import org.lc.eic.messageendpoint.InboundEndpoint;
import org.lc.eic.messageendpoint.exception.FailedProcessMessageException;

public class MessageListener implements javax.jms.MessageListener {

	private InboundEndpoint inboundEndpoint;

	public MessageListener(InboundEndpoint inboundEndpoint) {
		this.inboundEndpoint = inboundEndpoint;
	}

	public void onMessage(Message message) {
		if (message instanceof TextMessage) {
			String txt;
			try {
				txt = ((TextMessage) message).getText();
			} catch (JMSException e) {
				throw new RuntimeException("Failed getText()", e);
			}
			try {
				inboundEndpoint.onMessage(new ByteArrayInputStream(txt.getBytes()));
			} catch (FailedProcessMessageException e) {
				throw new RuntimeException(e);
			}
		} else if (message instanceof BytesMessage) {

			final BytesMessage bytesMessage = (BytesMessage) message;

			InputStream instream = new InputStream() {

				public int read(byte[] b) throws IOException {

					try {
						return bytesMessage.readBytes(b);
					} catch (JMSException e) {
						throw new IOException("Failed read byte buffer.", e);
					}
				}

				public int read() throws IOException {
					byte[] oneByte = new byte[1];
					try {
						bytesMessage.readBytes(oneByte);
						return oneByte[0];
					} catch (JMSException e) {
						throw new IOException("Failed read byte.", e);
					}
				}
			};

			try {
				inboundEndpoint.onMessage(instream);
			} catch (FailedProcessMessageException e) {
				throw new RuntimeException(e);
			}
		} else if (message instanceof StreamMessage) {
			final StreamMessage streamMessage = (StreamMessage) message;

			InputStream instream = new InputStream() {

				public int read(byte[] b) throws IOException {

					try {
						return streamMessage.readBytes(b);
					} catch (JMSException e) {
						throw new IOException("Failed read byte buffer.", e);
					}
				}

				public int read() throws IOException {
					try {
						return streamMessage.readByte();
					} catch (JMSException e) {
						throw new IOException("Failed read byte.", e);
					}
				}
			};
			try {
				inboundEndpoint.onMessage(instream);
			} catch (FailedProcessMessageException e) {
				throw new RuntimeException(e);
			}

		} else{
			
			throw new RuntimeException("Unsupported message type: "+message.getClass().getName());
		}

	}

}
